perm filename PXLTYP.PSC[MF,ALS] blob
sn#637050 filedate 1984-06-22 generic text, type T, neo UTF8
program PXLTYP;
(*
Type out a PXL file.
(c) 1981 by David Fuchs
*)
LABEL 9; (* go here to abort *)
CONST
copyright=' Copyright (C) 1981 by David Fuchs. ';
PXLID=1001; (* this pgm works for this version of PXL *)
MAXPXL=80000; (* max no of words in pxl file we can read *)
FIXPERPT=1048576; (* FIX's per point -- 1pt=2↑20fix *)
TYPE
(* here we disect words into bytes *)
/* DEC */
eightbit=0..255;
sixteenbit=0..65535;
thirtytwobit=0..4294967294;
oneoffour=1..4;
hack=packed record
case oneoffour of
1:( xword: integer);
2:( word: thirtytwobit;
junkc:0..15);
3:( leftsixteen:sixteenbit;
rightsixteen:sixteenbit;
junka:0..15);
4:( byte0:eightbit;
byte1:eightbit;
byte2:eightbit;
byte3:eightbit;
junkb:0..15);
end;
/* ENDDEC */
/* IBM
eightbit=packed 0..255;
sixteenbit=packed 0..65535;
oneofthree=packed 1..3;
hack=packed record
case oneofthree of
1:( word: integer);
2:( leftsixteen:sixteenbit;
rightsixteen:sixteenbit);
3:( byte0:eightbit;
byte1:eightbit;
byte2:eightbit;
byte3:eightbit);
end;
ENDIBM */
VAR
/* DEC */
terout, typfil: packed file of char;
i,j,k:integer; fnam:packed array[1..99] of char; (* for file name hack *)
/* ENDDEC */
/* IBM
terout, typfil: text;
ENDIBM */
pxlfil: file of integer;
pxl: array[0..MAXPXL] of hack; (* image of PXL file *)
pxllen: integer; (* number of words in PXL file *)
directoryptr: integer; (* second-to-last word in pxl file *)
designsize: real; (* from third-to-last word *)
magnification: integer; (* fourth-to-last *)
checksum: integer; (* fifth-to-last *)
ch: integer;
(* utility routines *)
(* returns the 'printing length' of an integer *)
function plen(i:integer):integer;
var ans: integer;
begin
if i<0 then begin i:=0-i; ans:=1; end
else ans:=0;
repeat
i:=i div 10;
ans:=ans+1;
until i=0;
plen:=ans;
end;
procedure jfns(var s:string; var chan:file; bits:integer); extern;
(* puts name of file open on chan into s. Format depends on bits, ala tops20 JFNS *)
procedure error(err,parm:integer);
CONST MAXE=7; (* error numbers are in the range 1..MAXE *)
var fatal:boolean; cont,knt:integer;
begin
writeln(terout);
if err>0 then fatal:=false
else begin
fatal:=true;
err:=-err;
write(terout,'FATAL ');
end;
writeln(terout,'PXLTYP error (number ',err:plen(err),')');
if (0<err) and (err<=MAXE) then case err of
1: writeln(terout,'PXL file too long; I can only handle ',
parm:plen(parm),'words.');
2: writeln(terout,'Low order 4 bits of word ',
parm:plen(parm),' not 0.');
3: writeln(terout,'Word 0=',parm:plen(parm),', which is not PXLID.');
4: writeln(terout,'Last Word=',parm:plen(parm),
', which is not PXLID.');
5: writeln(terout,'Directory Pointer = ',parm:plen(parm),
', which isn''t consistent with the length of the PXL file.');
6: writeln(terout,'Raster Pointer for character ',parm:plen(parm),
' out of range.');
7: writeln(terout,'Raster Pointer for character ',parm:plen(parm),
' out of range, considering this char''s raster size.');
end (* of case *)
else begin
writeln(terout,'Bad error number in PXLTYP! ',err:plen(err));
fatal:=true;
end;
if fatal then begin
writeln(terout,'Fatal error.');
goto 9;
end;
end;
function unfix(f:integer):real;
var h:hack; i:integer;
begin
h.word:=f;
if h.leftsixteen<32768 then i:= h.leftsixteen*65536+h.rightsixteen
else i:=(h.leftsixteen-65535)*65536+(h.rightsixteen-65536);
unfix:=i/fixperpt; (* converts a FIX integer to a real number of pts *)
end;
(* write out an integer the right way *)
procedure writeint(int:integer);
procedure wint(int:integer);
begin
if int>0 then begin
wint(int div 10);
write(typfil,(int mod 10):1);
end;
end;
begin
if int=0 then write(typfil,'0')
else begin
if int<0 then begin write(typfil,'-'); int:=0-int; end;
wint(int);
end;
end;
(* write out an octal number, almost the right way *)
procedure writeoct(oct:integer);
var i:integer;
procedure woct(oct:integer);
begin
if oct>0 then begin
woct(oct div 8);
write(typfil,(oct mod 8):1);
end;
end;
begin
write(typfil,'''');
if oct=0 then write(typfil,'0')
else begin
if oct<0 then begin
write(typfil,'-');
oct:=-oct; (* small bug here, if oct=-MAXINT *)
end;
woct(oct);
end;
end;
(* write out a real number in a reasonable fashion *)
procedure writereal(r:real;dp:integer);
var i:integer;
begin
if r<0 then begin r:=0.0-r; write(typfil,'-'); end;
if r=0.0 then begin
write(typfil,'0.');
for i:=1 to dp do write(typfil,'0');
end
else begin
(* do integer part *)
i:=trunc(r);
writeint(i);
(* do fractional part *)
r:=r-i;
write(typfil,'.');
for i:=1 to dp do begin
r:=r*10;
write(typfil,trunc(r):1);
r:=r-trunc(r);
end;
end;
end;
procedure writepix(pix,bits: integer);
var bit,i:integer;
begin
bit:=32768;
for i:=1 to bits do begin
if odd(pix div bit) then write(typfil,'X')
else write(typfil,'.');
bit:=bit div 2;
end;
end;
procedure readinpxlfile;
begin
pxllen:=0;
while (pxllen<MAXPXL) and (not eof(pxlfil)) do begin
/* DEC */
pxl[pxllen].xword:=pxlfil↑;
/* ENDDEC */
/* IBM
pxl[pxllen].word:=pxlfil@;
ENDIBM */
get(pxlfil);
pxllen:=pxllen+1;
end;
if not eof(pxlfil) then error(1,pxllen);
end;
procedure checkpxlformat;
var words,i:integer;
begin
/* DEC */
for i:=0 to pxllen-1 do if pxl[i].junka<>0 then error(2,i);
/* ENDDEC */
if pxl[0].word<>PXLID then error(3,pxl[0].word);
if pxl[pxllen-1].word<>PXLID then error(4,pxl[pxllen-1].word);
directoryptr:=pxl[pxllen-2].word;
if directoryptr<>pxllen-517 then error(5,directoryptr);
designsize:=unfix(pxl[pxllen-3].word);
write(typfil,'Design size ');
writereal(designsize,4); writeln(typfil,' pt.');
magnification:=pxl[pxllen-4].word;
write(typfil,'Magnification ');
writereal(magnification,0); writeln(typfil);
checksum:=pxl[pxllen-5].word;
write(typfil,'Checksum '); writeoct(checksum); writeln(typfil);
for i:=0 to 127 do begin
if pxl[directoryptr+i*4+2].word >= directoryptr
then error(6,i);
words:=((pxl[directoryptr+i*4].leftsixteen+31) div 32)
* (pxl[directoryptr+i*4].rightsixteen);
if pxl[directoryptr+i*4+2].word + words > directoryptr
then error(7,i);
end;
(* doesn't check overlapping of chars' pixels *)
end;
procedure printpxlch(ch:integer);
var dptr,rptr,ph,pw,offset,tpw,i:integer; width:real;
begin
writeln(typfil);
write(typfil,'Char '); writeoct(ch); writeln(typfil);
dptr:=directoryptr+ch*4;
pw:=pxl[dptr].leftsixteen;
write(typfil,'Pixel Width '); writeint(pw);
ph:=pxl[dptr].rightsixteen;
write(typfil,' Pixel Height '); writeint(ph); writeln(typfil);
write(typfil,'X-offset ');
offset:=pxl[dptr+1].leftsixteen;
if offset>32767 then offset:=offset-65536;
writeint(offset);
write(typfil,' Y-offset ');
offset:=pxl[dptr+1].rightsixteen;
if offset>32767 then offset:=offset-65536;
writeint(offset);
writeln(typfil);
rptr:=pxl[dptr+2].word;
write(typfil,'Raster Pointer '); writeint(rptr); writeln(typfil);
width:=unfix(pxl[dptr+3].word);
write(typfil,'Width '); writereal(width,5); write(typfil,' (');
writereal(width*designsize,4); writeln(typfil,' pt.)');
for i:=1 to ph do begin
tpw:=pw;
while tpw>31 do begin
writepix(pxl[rptr].leftsixteen,16);
writepix(pxl[rptr].rightsixteen,16);
tpw:=tpw-32;
rptr:=rptr+1;
end;
if tpw>0 then begin
if tpw>15 then begin
writepix(pxl[rptr].leftsixteen,16);
if tpw>16 then
writepix(pxl[rptr].rightsixteen,tpw-16);
end
else if tpw>0 then writepix(pxl[rptr].leftsixteen,tpw);
rptr:=rptr+1;
end;
writeln(typfil);
(* bug-should check righthand pixels for emptyness (>pw) *)
end;
end;
procedure doit;
begin
readinpxlfile;
checkpxlformat;
for ch:=0 to 127 do begin write(terout,ch:4); printpxlch(ch); end;
end;
(* And here we go...main program *)
begin
/* DEC */
rewrite(terout,'TTY:');
writeln(terout,copyright);
write(tty,'PXL file(s): '); reset(pxlfil,'':@); writeln(tty);
jfns(fnam,pxlfil,001000000000B);
i:=1; while ord(fnam[i])>0 do i:=i+1;
j:=i;
fnam[j]:='.'; j:=j+1;
fnam[j]:='T'; j:=j+1;
fnam[j]:='Y'; j:=j+1;
fnam[j]:='P'; j:=j+1;
fnam[j]:=chr(0);
write(tty,'Writing ');
for k:=1 to j do write(tty,fnam[k]);
writeln(tty);
rewrite(typfil,fnam);
for k:=1 to i-1 do write(typfil,fnam[k]);
writeln(typfil);
doit;
/* ENDDEC */
/* IBM
rewrite(terout);
writeln(terout,copyright);
reset(pxlfil,'DDNAME=PXL');
rewrite(typfil,'DDNAME=TYP');
doit;
ENDIBM */
9:
end.